/*
 * bw_json_tool.h
 *
 *  Created on: 2018年9月6日
 *  Author: Degang.Wu (windragon@126.com)
 *  Desc:
 */

#ifndef BW_JSON_TOOL_H_
#define BW_JSON_TOOL_H_

#include "../../common/cJSON.h"
#include "bw_Str.h"
#include "../inc/rapidjson/rapidjson.h"
#include "../inc/rapidjson/document.h"     // rapidjson's DOM-style API
#include "../inc/rapidjson/prettywriter.h" // for stringify JSON
#include "../inc/rapidjson/pointer.h"

#define BW_JSON_GET_STR_VAL(obj, key, dst, dst_len, default_val) do {    \
    cJSON* item = cJSON_GetObjectItem(obj, key);    \
    if (bw_json_is_string(item) && item->valuestring) {    \
        strncpy(dst, item->valuestring, dst_len);    \
    } else {    \
        strncpy(dst, default_val, dst_len);    \
    }    \
}while(0);

#define BW_JSON_GET_CHAR_VAL(obj, key, dst, default_val) do {    \
    cJSON* item = cJSON_GetObjectItem(obj, key);    \
    if (bw_json_is_string(item) && item->valuestring) {    \
        dst = *(item->valuestring);    \
    } else {    \
        dst = default_val;    \
    }    \
}while(0);

#define BW_JSON_GET_INT_VAL(obj, key, dst, default_val) do {    \
    cJSON* item = cJSON_GetObjectItem(obj, key);    \
    if (bw_json_is_num(item)) {    \
        dst = item->valueint;    \
    } else if (bw_json_is_string(item)) {    \
        dst = atoi(item->valuestring);    \
    }    \
    else {    \
        dst = default_val;    \
    }    \
}while(0);

#define BW_JSON_GET_LONGLONG_VAL(obj, key, dst, default_val) do {    \
    cJSON* item = cJSON_GetObjectItem(obj, key);    \
    if (bw_json_is_num(item)) {    \
        dst = item->valueint;    \
    } else if (bw_json_is_string(item)) {    \
        dst = atoll(item->valuestring);    \
    }    \
    else {    \
        dst = default_val;    \
    }    \
}while(0);


#define BW_JSON_GET_DOUBLE_VAL(obj, key, dst, default_val) do {    \
    cJSON* item = cJSON_GetObjectItem(obj, key);    \
    if (bw_json_is_num(item)) {    \
        dst = item->valuedouble;    \
    } else if (bw_json_is_string(item)) {    \
        dst = atof(item->valuestring);    \
    }    \
    else {    \
        dst = default_val;    \
    }    \
}while(0);

namespace bwcgi {

    int bw_json_is_array(cJSON *item);

    int bw_json_is_obj(cJSON *item);

    int bw_json_is_string(cJSON *item);

    int bw_json_is_num(cJSON *item);

    inline void RAPIDJSON_GET_STR_VAL(rapidjson::Document &obj, const char *key, string &dst, const char *defVal) {
        dst.clear();
        if ((nullptr == key) || (nullptr == defVal))
            return;
        dst = defVal;
        if (obj.HasMember(key) && obj[key].IsString()) {
            dst = obj[key].GetString();
            bwcgi::BWStr::trim(dst);
        }
    }

    inline void RAPIDJSON_GET_STR_VAL(rapidjson::Value &obj, const char *key, string &dst, const char *defVal) {
        dst.clear();
        if ((nullptr == key) || (nullptr == defVal))
            return;
        dst = defVal;
        if (obj.HasMember(key) && obj[key].IsString()) {
            dst = obj[key].GetString();
            bwcgi::BWStr::trim(dst);
        }
    }

    inline void RAPIDJSON_GET_INT_VAL(rapidjson::Document &obj, const char *key, int &dst, int defVal) {
        if (nullptr == key)
            return;
        dst = defVal;
        if (obj.HasMember(key) && obj[key].IsInt()) {
            dst = obj[key].GetInt();
        }
    }

    inline void RAPIDJSON_GET_INT_VAL(rapidjson::Value &obj, const char *key, int &dst, int defVal) {
        if (nullptr == key)
            return;
        dst = defVal;
        if (obj.HasMember(key) && obj[key].IsInt()) {
            dst = obj[key].GetInt();
        }
    }

}


#endif /* BW_JSON_TOOL_H_ */
